home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / castools.zip / FINDENTR.C < prev    next >
Text File  |  1990-02-02  |  6KB  |  190 lines

  1.  
  2.  
  3. /*
  4.    FINDENTR.C  Function PbFindFirstOrNext: finds a phonebook entry (individual
  5.       or group) based on its name.
  6.  
  7.    INPUT:  Phonebook structure, possibly memory space to hold the entry, and a
  8.       name string specification or record ID.
  9.  
  10.    OUTPUT: If successful, a pointer to a phonebook entry structure holding the
  11.       requested entry, as well as the record ID of the next entry that matches
  12.       the same name string spec, if any.
  13. */
  14.  
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <malloc.h>
  18. #include <string.h>
  19. #include <phonebk.h>
  20.  
  21. PBE * pascal PbFindFirstOrNext(PB *pb,
  22.                                PBE *entry,
  23.                                char *name,
  24.                                int *recordID)
  25. {
  26.  
  27.   PBE *pbe;
  28.   char searchst[32],               /* wildcard coded search string */
  29.        testst[32];                 /* fetched and converted string from entry*/
  30.  
  31.   PBEFIXED fixed_part, *result;              /* for call to GetFixedPart() */
  32.   char *vbl_part = NULL;                     /* for holding the rest of entry */
  33.   size_t vbl_length;                         /* length of entry variable part */
  34.  
  35.   int FirstFound = 0,
  36.       start,                                 /* rid where search starts */
  37.       i, j, k,                               /* loop counters */
  38.       red;                                   /* for return value of fread() */
  39.   int temperrno = 0;                         /* for saving aside Pberrno */
  40.  
  41.   Pberrno = 0;                               /* Initially, always reset */
  42.  
  43.   /* First, check params */
  44.   if ((pb == NULL) ||
  45.       (name == NULL) ||
  46.       (recordID == NULL)) {
  47.     Pberrno = INVALIDPARAMETER;
  48.     return(NULL);
  49.   }
  50.   if ((*recordID < -1) ||
  51.       (*recordID > 999)) {
  52.     Pberrno = INVALIDPARAMETER;
  53.     return(NULL);
  54.   }
  55.  
  56.   /* Decide whether we're allocating the memory, or caller has provided */
  57.   if (!entry) {
  58.     if (!(pbe = (PBE *)calloc(1, sizeof(PBE)))) {
  59.       Pberrno = OUTOFMEM;
  60.       return(NULL);
  61.     }
  62.     if (!(pbe->fields = (char **)calloc(pb->header.fields,
  63.                                         sizeof(char *)))) {
  64.       Pberrno = OUTOFMEM;
  65.       goto error_out;
  66.     }
  67.     for (i=0; i<pb->header.fields; i++) {
  68.       if (!(pbe->fields[i] = (char *)calloc(60, sizeof(char)))) {
  69.         Pberrno = OUTOFMEM;
  70.         goto error_out;
  71.       }
  72.     }
  73.     /* Can't allocate the membership list yet: don't know how many members */
  74.   }
  75.   else {
  76.     pbe = entry;
  77.   }
  78.  
  79.   /* Convert name parameter to internal search string */
  80.   strncpy(searchst, name, NAMELENGTH);
  81.   for (i=0; i<NAMELENGTH; i++) {
  82.     if (searchst[i] == '*') {
  83.       for (j=i; j<NAMELENGTH; j++) {
  84.         searchst[j] = '?';
  85.       }
  86.       searchst[j-1] = '\0';
  87.       break;
  88.     }
  89.   }
  90.  
  91.   /* Decide where to start search: If a "FindFirst", start at top */
  92.   if (*recordID == -1) {
  93.     start = 0;
  94.   }
  95.   else {
  96.     start = *recordID;
  97.   }
  98.   for (*recordID = start; *recordID < MAXENTRIES; (*recordID)++) {
  99.     result = GetFixedPart(pb, &fixed_part, *recordID);
  100.     if (result) {
  101.       strncpy(testst, fixed_part.name, NAMELENGTH);
  102.       for (i=0; i<NAMELENGTH; i++) {
  103.         if (searchst[i] == '?') {
  104.           testst[i] = '?';
  105.         }
  106.       }
  107.  
  108.       /* Compare the two strings */
  109.       if (!(strnicmp(searchst, testst, NAMELENGTH))) {   /* they match */
  110.         if (FirstFound) {
  111.           break;
  112.         }
  113.         else {
  114.  
  115.           /* Set flag (found 1); copy fixed part, and allocate for members */
  116.           FirstFound = 1;
  117.           memcpy(pbe, &fixed_part, sizeof(PBEFIXED));
  118.           if (!entry) {
  119.             if (!(pbe->MemberList = (int *)malloc(pbe->members *
  120.                                                sizeof(int)))) {
  121.               Pberrno = OUTOFMEM;
  122.               goto error_out;
  123.             }
  124.           }
  125.  
  126.           /* Read the rest of the entry into a buffer */
  127.           if (vbl_length = pbe->length - sizeof(PBEFIXED)) {
  128.             if (!(vbl_part = (char *)malloc(vbl_length))) {
  129.               Pberrno = OUTOFMEM;
  130.               goto error_out;
  131.             }
  132.             red = fread(vbl_part, 1, vbl_length, pb->fp);
  133.             if (red != vbl_length) {
  134.               Pberrno = CANTREAD;
  135.               goto error_out;
  136.             }
  137.  
  138.             /* if read successful, fill in entry's variable fields */
  139.             if (pbe->type == PERSONENTRY) {
  140.               for (i=0, j=0; i<pb->header.fields; i++, j++) {
  141.                 for (k=0; k<MAXFIELDSIZE; k++, j++) {
  142.                   if (!(pbe->fields[i][k] = vbl_part[j])) {
  143.                     break;
  144.                   }
  145.                 }
  146.               }
  147.             }
  148.             else {
  149.               j = 0;
  150.             }
  151.             for (i=0; i<pbe->members; i++) {
  152.               pbe->MemberList[i] = ((int *)(vbl_part + j))[i];
  153.             }
  154.             free(vbl_part);
  155.           }
  156.         }
  157.       }    /* else: no match: just go on searching */
  158.     }      /* else: no entry at that rid: just go on searching */
  159.   }        /* end of searching: either found 2 or reached MAXENTRIES */
  160.   if (*recordID == MAXENTRIES) {
  161.     if (FirstFound) {
  162.       *recordID = -1;
  163.       Pberrno = NOMOREMATCH;
  164.       return(pbe);          /* Not an error, but only found one */
  165.     }
  166.     else {
  167.       Pberrno = NOENTRYFOUND;       /* Didn't find any */
  168.       goto error_out;
  169.     }
  170.   }
  171.  
  172.   /* Not only found one, but a second */
  173.   return(pbe);
  174.  
  175. error_out:
  176.   if (vbl_part) {
  177.     free(vbl_part);
  178.   }
  179.   if (Pberrno) {
  180.     temperrno = Pberrno;
  181.   }
  182.   if (!entry) {
  183.     PbFreePBE(pb, pbe);
  184.   }
  185.   if (temperrno) {
  186.     Pberrno = temperrno;
  187.   }
  188.   return(NULL);
  189. }
  190.